package logs

import (
	"fmt"
	"os"
	"path"
	"strings"
	"time"

	rotatelogs "github.com/lestrrat-go/file-rotatelogs"
	"go.uber.org/zap"
	"go.uber.org/zap/zapcore"

	"eci-forward/pkg/config"
)

var Logger *zap.Logger

const LogRotationTime = 24 * time.Hour
const MaxLogAge = 15 * 24 * time.Hour
const DateLogFileFormat = "%Y-%m-%d"

func GetDateLogFileName(logFile string) string {
	if !strings.Contains(logFile, DateLogFileFormat) {
		return logFile + "." + DateLogFileFormat
	}
	return logFile
}

func Init() {
	logFile := config.GetBasicConfig().LogFile
	logLevel := config.GetBasicConfig().LogLevel
	logDir := path.Dir(logFile)
	_, err := os.Stat(logDir)
	if os.IsNotExist(err) {
		err = os.MkdirAll(logDir, 0755)
		if err != nil {
			message := fmt.Sprintf("Could not create log directory: %v", err)
			panic(message)
		}
	}
	zapLogLevel, err := zapcore.ParseLevel(logLevel)
	if err != nil {
		panic("Wrong log level format set from environment, use lower-case level string")
	}

	encoderConfig := zap.NewProductionEncoderConfig()
	// time format in logs
	encoderConfig.TimeKey = "date"
	encoderConfig.LevelKey = zapLogLevel.String()
	encoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder
	// use json type logs with JSONEncoder
	encoder := zapcore.NewJSONEncoder(encoderConfig)

	dateLogFile := GetDateLogFileName(logFile)
	rotator, err := rotatelogs.New(
		dateLogFile,
		rotatelogs.WithMaxAge(MaxLogAge),
		rotatelogs.WithRotationTime(LogRotationTime))
	if err != nil {
		panic("Failed to init rotatelogs writer: " + err.Error())
	}
	fileWriteSyncer := zapcore.AddSync(rotator)
	core := zapcore.NewTee(
		// use stdout and filewriter at the same time
		zapcore.NewCore(encoder, zapcore.AddSync(os.Stdout), zapLogLevel),
		zapcore.NewCore(encoder, fileWriteSyncer, zapLogLevel),
	)
	Logger = zap.New(core)
}
